//
// Created by wty on 22-7-13.
//
#include "sylar/bytearray.h"
#include "sylar/sylar.h"

sylar::Logger::ptr logger = SYLAR_LOG_ROOT();

void test(){
#define XX(type, len, write_fun, read_fun, base_len)                          {\
    std::vector<type> vec;                                                     \
    for(int i=0;i<len;i++){                                                    \
        vec.push_back(rand());                                                 \
    }                                                                          \
    sylar::ByteArray::ptr ba(new sylar::ByteArray(base_len));                  \
    for(auto &i:vec){                                                          \
        ba->write_fun(i);                                                      \
    }                                                                          \
    ba->setPosition(0);                                                        \
    for(size_t i=0;i<vec.size();i++){                                          \
        type v = ba->read_fun();                                               \
        SYLAR_ASSERT(v==vec[i]);                                               \
    }                                                                          \
    SYLAR_ASSERT(ba->getReadSize()==0);                                        \
    SYLAR_LOG_INFO(logger)<< #write_fun " / " #read_fun " { " #type " } len"   \
                << " base_len = "<<base_len << " size "<< ba->getSize();      }
                            
    XX(int8_t, 10, writeFint8, readFint8, 800);          //固定长度
    XX(uint8_t, 100, writeFuint8, readFuint8, 1);
    XX(int16_t, 100, writeFint16, readFint16, 1);
    XX(uint16_t, 100, writeFuint16, readFuint16, 1);
    XX(int32_t, 100, writeFint32, readFint32, 1);
    XX(uint32_t, 100, writeFuint32, readFuint32, 1);
    XX(int64_t, 100, writeFint64, readFint64, 1);
    XX(uint64_t, 100, writeFuint64, readFuint64, 1);

    XX(int32_t, 100, writeInt32, readInt32, 1);          //非固定长度
    XX(uint32_t, 100, writeUint32, readUint32, 1);
    XX(int64_t, 100, writeInt64, readInt64, 1);
    XX(uint64_t, 100, writeUint64, readUint64, 1);

#undef XX

/* 
 * 测试用例设计：
 * 在前面的测试基础上，增加对字符串序列化/反序列化的测试
 */
#define XX(len, write_fun, read_fun, base_len)                    \
    {                                                             \
        std::string s = "qwertyuiopasdfghjklzxcvbnm";             \
        std::vector<std::string> vec;                             \
        for (int i = 0; i < len; i++) {                           \
            random_shuffle(s.begin(), s.end());                   \
            vec.push_back(s);                                     \
        }                                                         \
        sylar::ByteArray::ptr ba(new sylar::ByteArray(base_len)); \
        for (auto &i : vec) {                                     \
            ba->write_fun(i);                                     \
        }                                                         \
        ba->setPosition(0);                                       \
        for (size_t i = 0; i < vec.size(); ++i) {                 \
            std::string v = ba->read_fun();                       \
            SYLAR_ASSERT(v == vec[i]);                            \
        }                                                         \
        SYLAR_ASSERT(ba->getReadSize() == 0);                     \
        SYLAR_LOG_INFO(logger) << #write_fun "/" #read_fun        \
                                               " ("               \
                                               "string"           \
                                               ") len="           \
                                 << len                           \
                                 << " base_len=" << base_len      \
                                 << " size=" << ba->getSize();    \
    }
    XX(100, writeStringF16, readStringF16, 10);
    XX(100, writeStringF32, readStringF32, 10);
    XX(100, writeStringF64, readStringF64, 10);
    XX(100, writeStringVint, readStringVint, 26);
#undef XX

}

int main(int argc, char** argv){
    test();
    std::vector<int> v1{1,2,3,4,5,6};
    std::random_shuffle(v1.begin(), v1.end());
    for(auto &i: v1){
        std::cout<<i<<" ";
    }
    return 0;
}